El objetivo de esta notebook es aprender los pilares de
ggplot2 y
library(ggplot2)
library(plotly)##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(dplyr)##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(viridis)## Loading required package: viridisLite
df <- read.csv('data/pokemon.csv')ggplot2 es un potente paquete para la elaboración de
gráficos en R y que funciona a través de pipelines (el operador
pipeline es +`). Dentro de este flujo de trabajo existen
varias funciones y parámetros que son fundamentales para la elaboración
de un gráfico:
ggplot() - función base para la construcción del gráfico
geom - funciones que especifican el tipo de representación de los datos (puntos, líneas, boxplots…) y se añaden al gráfico base mediante capas
data - parámetro que indica el dataframe a partir del cual se construirá el gráfico
aes() - función en la que se especifican qué variables del dataframe se incluyirán en el gráfico y cómo
De esta forma, para construir por ejemplo un gráfico scatter plot con nuestro datset de Pokémon en el que queremos colocar los puntos de ataque (attack) en el eje x y los de defensa (defense) en el eje y, realizaríamos lo siguiente. Date cuenta de que por defecto ordena ambos ejes de menor a mayor 🤔.
ggplot(data=df, aes(x=attack, y=defense)) +
geom_point()Todo lo especificado en ggplot() es heredado por el
resto de funciones, aunque es posible pasar directamente los datos y
variables en las funciones geom que usemos (útil para combinar
diferentes visualizaciones, como veremos más adelante 🤫).
ggplot() +
geom_point(data=df, aes(x=attack, y=defense))Es posible introducir en aes() también una tercera o
cuarta variable para establecer tamaños o colores. Aunque en función del
geom que estemos usando puede tener variaciones. Consulta para ello la
ayuda de cada función 🧐.
help('geom_point')En base a lo que admite geom_point() voy a incluir la en
color la defensa (defense) y en tamaño los puntos de vida
(hp).
ggplot(data=df, aes(x=attack, y=defense, color=base_total, size=hp)) +
geom_point()Estos parámetros no tienen que estar asociados a una variable, pueden
ser una constante. Por ejemplo, se puede indicar que el tamaño sea en
todos los casos el mismo valor. Aunque debes indicarlo directamente en
la función geom correspondiente y fuera de aes().
ggplot(data=df, aes(x=attack, y=defense)) +
geom_point(size=2, color='#ffc83d')Algunos apuntes importantes antes de continuar:
df_plot <- ggplot(data=df, aes(x=attack, y=defense, color=base_total))
df_plot +
geom_point(size=2)Ten en cuenta que tipo de variable tienes, confundir variables
discretas y continuas es común 🤕. Si tenemos un variable de tipo
integer automáticamente la tomara como continua, pero si es
discreta tenemos que modificarla antes.
ggplot(data=df, aes(x=attack, y=defense, color=generation)) +
geom_point(size=2)df$generation <- as.character(df$generation)
ggplot(data=df, aes(x=attack, y=defense, color=generation)) +
geom_point(size=2)Combinar dos gráficos (capas) es muy sencillo, solo tienes que añadir dos geoms. Pero ten en cuenta que variables quieres usar, pues es posible que tengas que especificarlas directamente dentro de estas.
ggplot(data=df, aes(x=attack, y=defense, color=generation)) +
geom_point(size=2)Ahora que ya conocemos un poco la forma de trabajar básica de
ggplot2, vamos a conocer los principales gráficos que
podemos hacer.
Podemos construir gráficos de lineas con geom_line(), de
manera obligatoria es necesario indicar la posición de x e y. Por
ejemplo, la evolución del ataque (attack) de los Pokémon por
orden de posición en la Pokédex (pokedex_number), coloreando
las líneas en base a la generación (generation).
ggplot(data=df, aes(x=pokedex_number, y=attack, color=generation)) +
geom_line()Es posible hacer lineas de regresión mediante
geom_smooth(). Por defecto estimará el tipo de regresión
que mejor se ajusta.
ggplot(data=df, aes(x=pokedex_number, y=attack, color=generation)) +
geom_line() +
geom_smooth()## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Fíjate en el ejemplo, que agrupa por generación porque de base le
digo que establezca dicha diferencia 🥴. Si quisiera una línea de
regresión general, una opción sería hacer esa distinción de color
específica de geom_line().
ggplot(data=df, aes(x=pokedex_number, y=attack)) +
geom_line(aes(color=generation)) +
geom_smooth()## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Esta opción ya la vimos antes, para hacer un scatter plot
solo tenemos que usar geom_point() y de manera obligatoria
incluir las posiciones de x e y. Por ejemplo, el ataque
(attack) en x y el ataque especial (sp_attack) en y,
coloreo si es legendario o no (is_legendary).
*antes tengo que transformarla en discreta 🤫
df$is_legendary <- as.character(df$is_legendary)
ggplot(data=df, aes(x=attack, y=sp_attack, color=is_legendary)) +
geom_point()Aquí tenemos dos opciones. Por un lado geom_bar()
permite generar barras de frecuencia de una variable. Solo necesitas
especificar la variable en x o y. Por ejemplo, la frecuencia de Pokémon
por primer tipo (type1).
ggplot(data=df, aes(x=type1)) +
geom_bar()Mientras que en geom_col() en lugar de calcular la
función la altura en base a la frecuencia, esta debe venir dada. Es
necesario tanto x como y. Para este ejemplo voy a crear un dataframe
nuevo con los promedios de ataque por tipo 1.
df_avg <- df[,c('type1', 'attack')] %>%
group_by(type1) %>%
summarise(attack = mean(attack))
ggplot(data=df_avg, aes(x=type1, y=attack)) +
geom_col()Realizar un histograma es muy sencillo 🙂 con la función
geom_histogram(). Solo es necesario indicar la variable en
x o y. Puedes establecer el número de bins con el parámetro
bins. Por ejemplo, el histograma de velocidad (speed) de
los Pokémon usando 25 bins.
ggplot(data=df, aes(x=speed)) +
geom_histogram(bins=25)Los diagramas de cajas y bigotes son un clásico y aquí puedes hacerlo
con geom_boxplot() solo necesitas indicar la variable en x
o y. Aunque ojo 👁️🗨️ puedes dividir esta variable de acuerdo a una
segunda. Por ejemplo, el ataque especial (sp_attack) por primer
tipo (type1).
ggplot(data=df, aes(x=type1, y=sp_attack)) +
geom_boxplot()Como te estarás dando cuenta, en gráficos como los de puntos no
aparecen las etiquetas con los nombres. Introducirlo es muy sencillo con
geom_text() indicando en el parámetro label la
variable que va a salir junto al punto. Por ejemplo, incluir en gráfico
del inicio los nombres de los Pokémon con más de 130 de ataque y defensa
(para que sea legible 😵).
ggplot(data=df, aes(x=attack, y=defense, color=base_total)) +
geom_point() +
geom_text(data=df[which(df$attack>130 & df$defense>130),], aes(x=attack, y=defense, label=name))Podemos establecer escalas de color de forma manual una vez indicado
que esta escala viene dada por una variable. En el caso de variables
continuas podemos usar scale_color_gradient() para
establecer un degradado de color.
ggplot(data=df, aes(x=attack, y=defense, color=base_total)) +
geom_point() +
scale_color_gradient(low='blue', high='red')De hecho, existen muchos paquetes complementarios a
ggplot2 que añaden muchas posibilidades. Por ejemplo, con
viridis podemos usar la tradicional escala de colores con
la función scale_color_viridis().
ggplot(data=df, aes(x=attack, y=defense, color=base_total)) +
geom_point() +
scale_color_viridis()En el caso de variable discretas es muy sencillo, con
scale_color_manual() podemos hacerlo simplemente indicando
en values a que valor corresponde cada color.
ggplot(data=df, aes(x=attack, y=sp_attack, color=is_legendary)) +
geom_point() +
scale_color_manual(values=c('0'='#57a1d1', '1'='#bb3f25'))Por si no te diste cuenta, estos gráficos incluyen por defecto los
nombres de las variables en los ejes 🙃. Este problema se soluciona
rápidamente con labs() indicando para cada variable el
nombre exacto que queremos, e incluso podemos introducir un título.
ggplot(data=df, aes(x=attack, y=sp_attack, color=is_legendary)) +
geom_point() +
scale_color_manual(values=c('0'='#57a1d1', '1'='#bb3f25')) +
labs(x='Ataque', y='Ataque especial', title='Scatter plot de ataque y ataque especial de los Pokémon', color='Legendario')A tu gráfico ya le queda poco para ser pro 🥳. Puedes usar alguno de
los temas que ggplot2 incluye para mejorar el estilo del
gráfico. Yo voy a usar theme_classic().
ggplot(data=df, aes(x=attack, y=sp_attack, color=is_legendary)) +
geom_point() +
scale_color_manual(values=c('0'='#57a1d1', '1'='#bb3f25')) +
labs(x='Ataque', y='Ataque especial', title='Scatter plot de ataque y ataque especial de los Pokémon', color='Legendario') +
theme_classic()Sys.setenv("plotly_username"="Wences91")
Sys.setenv("plotly_api_key"="LaPmMF2lt51nQFyqE5j4")api_create(plot_ly(data=df, x=~attack, y=~sp_attack, split=~is_legendary, type='scatter', mode='markers'), filename='pokemons')## Found a grid already named: 'pokemons Grid'. Since fileopt='overwrite', I'll try to update it
## Found a plot already named: 'pokemons'. Since fileopt='overwrite', I'll try to update it
ggplotly(ggplot(data=df, aes(x=attack, y=sp_attack, color=is_legendary, text=name)) +
geom_point())ggplotly(ggplot(data=df, aes(x=speed)) +
geom_histogram(bins=25))